package sputils

import (
	"fmt"
	"gitee.com/ymofen/gobase"
	"gitee.com/ymofen/gobase/factory"
)

var (
	ErrInvalidObject = fmt.Errorf("invalid object")
)

// 参数转换器
type ArgsConverter interface {
	ConvertArgs(action int, confMap gobase.StrMap) interface{}
}

type KeyValueGetter interface {
	GetKeyValue(key string) (val interface{}, ok bool)
}

type SuperValue interface {
	StringByName(name string, def string) string
	String() string
	IsString() bool
	IsObject() bool
	Write2StrMap(strMap gobase.StrMap) int
	AsJSONStringEx(escape bool, format bool) string
	SetKeyValue(key string, val interface{})
	SetKeyValues(kvparse ...interface{})
	GetKeys() []string
}

type HealthyChecker interface {
	HealthyCheck() (ok bool, msg string)
}

type HealthyTernaryChecker interface {
	HealthyCheck() (ok gobase.Ternary, msg string)
}

type HealthyInt8Checker interface {
	HealthyCheck() (ok int8, msg string)
}

func NewSV(data []byte) (SuperValue, error) {
	if defaultCreateSupperValueFunc == nil {
		panic("create SuperValue func is empty")
	}
	return defaultCreateSupperValueFunc(data)
}

var (
	defaultCreateSupperValueFunc func(data []byte) (SuperValue, error)
)

func SetDefaultCreateSupperValueFunc(f func(data []byte) (SuperValue, error)) {
	defaultCreateSupperValueFunc = f
}

func ConvertArgs(obj interface{}, action int, confMap gobase.StrMap) interface{} {
	if lvintf, ok := obj.(ArgsConverter); ok {
		return lvintf.ConvertArgs(action, confMap)
	}
	return nil
}

func CheckCreateSPObjRef(conf gobase.StrMap) (*gobase.ObjectInnerRef, error) {
	conntype := conf.StringByName("conntype", "")
	conntype = fmt.Sprintf("sp.%s", conntype)
	obj, err := factory.CreateInstance(conntype, conf)
	if err != nil {
		return nil, err
	}

	if lvintf, ok := obj.(*gobase.ObjectInnerRef); ok {
		return lvintf, nil
	} else {
		return nil, fmt.Errorf("%s不是gobase.ObjectInnerRef对象", conntype)
	}
}
